package com.atguigu.gulimall.authserver.utils;
/**
 * @author 860620068
 * @Date 2021/6/11 :13:02
 * @desceiption:
*/

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 依赖的jar包有：commons-lang-2.6.jar 、httpclient-4.3.2.jar  httpcore-4.3.1.jar  common-io-2.4.jar
 */
public class HttpClientUtils {

    public static final int connTimeout=10000;
    public static final int readTimeout=10000;
    public static final String charset="UTF-8";
    private static HttpClient client = null;

    static{
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(128);
        cm.setDefaultMaxPerRoute(128);
        client = HttpClients.custom().setConnectionManager(cm).build();
    }
    public static String postParameters(String url,String parameterStr) throws GeneralSecurityException, IOException {
        return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
    }

    public static String postParameters(String url,String parameterStr,String charset,Integer connTimeout,Integer readTimeout) throws GeneralSecurityException, IOException {
        String post = post(url, parameterStr, "application/x-www-form-urlencoded", charset, connTimeout, readTimeout);
        return post;
    }

    public static String postParameters(String url, Map<String,String> params) throws GeneralSecurityException, IOException {
        return postForm(url,params,null,connTimeout,readTimeout);
    }

    public static String postParameters(String url,Map<String,String> params,Integer connTimeout,Integer readTimeout) throws GeneralSecurityException, IOException {
        return postForm(url,params,null,connTimeout,readTimeout);
    }

    public static String get(String url) throws IOException, GeneralSecurityException {
        return get(url,charset,null,null);
    }

    public static String get(String url,String charset) throws Exception{
        return get(url,charset,connTimeout,readTimeout);
    }

    /**
     * 发送一个GET请求
     *
     * @param url
     * @param charset
     * @param connTimeout  建立连接超时时间，毫秒
     * @param readTimeout  响应超时时间，毫秒
     * @return
     */
    private static String get(String url,String charset,Integer connTimeout,Integer readTimeout) throws IOException, GeneralSecurityException {
        HttpClient client = null;
        HttpGet get = new HttpGet(url);
        String result = "";
        try{
            //设置参数
            RequestConfig.Builder customReqConf = RequestConfig.custom();
            if(connTimeout!=null){
                customReqConf.setConnectTimeout(connTimeout);
            }
            if(readTimeout !=null){
                customReqConf.setSocketTimeout(readTimeout);
            }
            get.setConfig(customReqConf.build());

            HttpResponse res = null;

            if(url.startsWith("https")){
                //执行Https请求
                client = createSSLInsecureClient();
                res = client.execute(get);
            }else {
                //执行Http请求
                client = HttpClientUtils.client;
                res = client.execute(get);
            }
            result = IOUtils.toString(res.getEntity().getContent(),charset);
        }finally {
            get.releaseConnection();
            if(url.startsWith("https")&& client !=null && client instanceof CloseableHttpClient){
                ((CloseableHttpClient) client).close();
            }
        }
        return result;
    }

    /**
     * 提交form表单
     *
     * @param url
     * @param params
     * @param headers
     * @param connTimeout
     * @param readTimeout
     * @return
     */
    private static String postForm(String url, Map<String, String> params, Map<String,String> headers, Integer connTimeout, Integer readTimeout) throws GeneralSecurityException, IOException {
        HttpClient client = null;
        HttpPost post = new HttpPost(url);
        try{
            if(params!=null && !params.isEmpty()){
                List<NameValuePair> formParams = new ArrayList<>();
                Set<Map.Entry<String, String>> entrySet = params.entrySet();
                for(Map.Entry<String,String> entry:entrySet){
                    formParams.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
                post.setEntity(entity);
            }
            if(headers!=null && !headers.isEmpty()){
                for(Map.Entry<String,String> entry:headers.entrySet()){
                    post.addHeader(entry.getKey(),entry.getValue());
                }
            }
            //设置参数
            RequestConfig.Builder customReqConf = RequestConfig.custom();
            if(connTimeout !=null){
                customReqConf.setConnectTimeout(connTimeout);
            }
            if(readTimeout !=null){
                customReqConf.setSocketTimeout(readTimeout);
            }
            post.setConfig(customReqConf.build());
            HttpResponse res = null;
            if(url.startsWith("https")){
                //执行Https请求
                client = createSSLInsecureClient();
                res = client.execute(post);
            }
            return IOUtils.toString(res.getEntity().getContent(),"UTF-8");
        }finally {
            post.releaseConnection();
            if(url.startsWith("https") && client !=null && client instanceof CloseableHttpClient){
                ((CloseableHttpClient) client).close();
            }
        }
    }

    /**
     * 发送一个post请求，使用指定的字符集编码
     *
     * @param url
     * @param body  RequestBody
     * @param mimeType  例如： application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
     * @param charset 编码
     * @param connTimeout  建立连接超时时间，毫秒
     * @param readTimeout  相应超时时间，毫秒
     * @return
     */
    private static String post(String url, String body, String mimeType, String charset, Integer connTimeout, Integer readTimeout) throws GeneralSecurityException, IOException {
        HttpClient client = null;
        HttpPost post = new HttpPost(url);
        String result = "";

       try{
           if(StringUtils.isNotBlank(body)){
               HttpEntity entity = new StringEntity(body, ContentType.create(mimeType,charset));
               post.setEntity(entity);
           }
           //设置参数
           RequestConfig.Builder customReqConf = RequestConfig.custom();
           if(connTimeout !=null){
               customReqConf.setConnectionRequestTimeout(connTimeout);
           }
           if(readTimeout!=null){
               customReqConf.setSocketTimeout(readTimeout);
           }
           post.setConfig(customReqConf.build());

           HttpResponse res;
           if(url.startsWith("https")){
               //执行Https请求
               client = createSSLInsecureClient();
               res = client.execute(post);
           }else{
               //执行Http请求
               client =HttpClientUtils.client;
               res = client.execute(post);
           }
           result = IOUtils.toString(res.getEntity().getContent(),charset);
       }finally {
           post.releaseConnection();
           if(url.startsWith("https")&& client !=null && client instanceof CloseableHttpClient){
               ((CloseableHttpClient)client).close();
           }
       }
       return result;
    }

    /**
     * 创建SSL连接
     *
     * @return
     */
    private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {

        try{
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            }).build();

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
                @Override
                public void verify(String s, SSLSocket sslSocket) throws IOException {

                }

                @Override
                public void verify(String s, X509Certificate x509Certificate) throws SSLException {

                }

                @Override
                public void verify(String s, String[] strings, String[] strings1) throws SSLException {

                }

                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();

        } catch (GeneralSecurityException e) {
            throw e;
        }
    }
}








